package top.rish.universe.core.plugin;

import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import lombok.*;
import org.noear.solon.Solon;
import org.noear.solon.core.AppContext;
import org.noear.solon.core.Plugin;
import org.noear.solon.core.PluginEntity;
import org.noear.solon.core.util.ClassUtil;
import org.noear.solon.core.util.LogUtil;
import org.noear.solon.core.util.ResourceUtil;

import java.net.URL;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.List;
import java.util.Properties;

@Getter
@Setter
@ToString
@EqualsAndHashCode(callSuper = true)
public class UniversePluginEntity extends PluginEntity {

    private String id;
    private String name;
    private String version;
    private String author;
    private String description;
    private String url;
    private String domain;
    private Properties properties;

    private String classFilePath;

    private AppContext context;

    private List<UniPluginEntityDependency> dependencies;

    public UniversePluginEntity(ClassLoader classLoader, String className, Properties props) {
        super(classLoader, className, props);
    }


    public void restart(){
        this.prestop();
        this.stop();
        this.start(this.context);
    }


    @Override
    public void start(AppContext context) {
        Plugin plugin = this.getPlugin();
        if (plugin != null) {
            try {
                String className = this.getClassName();
                if((plugin instanceof UniversePlugin)){
                    ((UniversePlugin)plugin).startBefore(this, context);
                }else{
                    LogUtil.global().warn(StrUtil.format("This [class ==> {}] Plugin is not extends UniversePlugin !!!!",className));
                    plugin.start(context);
                }
            } catch (RuntimeException e) {
                throw e;
            } catch (Throwable e) {
                throw new IllegalStateException("Plugin start failed", e);
            }
        }
    }

    @Override
    public void init(AppContext context) {
        this.context =context;
        Plugin plugin = this.getPlugin();
        Properties props = this.getProps();
        if (plugin == null) {
            if (context != null && context.getClassLoader() !=null) {
                ClassLoader classLoader = context.getClassLoader();
                String className = this.getClassName();
                Plugin solonPlugin;
                UniversePlugin up;
                try{
                    up =  ClassUtil.tryInstance(classLoader, className);
                    up.setContext(context);
                    up.setProps(props);
                    up.setConfig(new PluginConfig(props));
                    plugin = up;
                }catch (ClassCastException e  ){
                    LogUtil.global().error(StrUtil.format("This [class ==> {}] Plugin is not extends UniversePlugin !!!!",className));
                    try{
                        solonPlugin = ClassUtil.tryInstance(classLoader, className);
                        plugin = solonPlugin;
                    }catch (ClassCastException se  ){
                        LogUtil.global().error(StrUtil.format("This [class ==> {}] Plugin is not implements Solon Plugin !!!!",className));
                    }
                }
                if (plugin == null) {
                    LogUtil.global().warn("The configured plugin cannot load: " + className);
                }else{
                    ReflectUtil.setFieldValue(this,"plugin",plugin);
                }
            }
        }
    }


}
